using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.Xna.Framework;
using Rocuna.HID.Interfaces;

namespace Rocuna.HID
{
    /// <summary>
    /// Manager class to manage all the inputs options.
    /// </summary>
    public class InputManager
    {
        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="InputManager"/> class.
        /// </summary>
        public InputManager()
        {
            RegisteredDevices = new List<IInputDevice>();
        }

        #endregion

        #region Properties

        private List<IInputDevice> RegisteredDevices { get; set; }

        #endregion

        #region Public methods

        /// <summary>
        /// Poll input by defention of Input devices.
        /// </summary>
        public void Poll()
        {
            Debug.WriteLine("Poll");
            foreach (var registeredDevice in RegisteredDevices.Where(d => d.IsActive))
            {
                registeredDevice.Poll();
            }
        }

        /// <summary>
        /// Registers the device.
        /// </summary>
        /// <param name="device">The device.</param>
        public void RegisterDevice(IInputDevice device)
        {
            RegisteredDevices.Add(device);
        }

        /// <summary>
        /// Unregister the device.
        /// </summary>
        /// <param name="device">The device.</param>
        public void UnregisterDevice(IInputDevice device)
        {
            (device as GameComponent).Dispose();
            RegisteredDevices.Remove(device);
        }

        /// <summary>
        /// Gets specific device by name.
        /// </summary>
        /// <param name="deviceName">Name of the device.</param>
        /// <returns></returns>
        public IInputDevice GetDevice(string deviceName)
        {
            return RegisteredDevices.FirstOrDefault(d => d.DeviceName == deviceName);
        }

        /// <summary>
        /// Registers the action to device.
        /// </summary>
        /// <param name="deviceName">Name of the device.</param>
        /// <param name="eventType">Type of the event.</param>
        /// <param name="action">The action.</param>
        public void RegisterActionToDevice(string deviceName, object eventType, Action<object> action)
        {
            var device = RegisteredDevices.FirstOrDefault(i => i.DeviceName == deviceName);
            if (device != null)
                device.RegisterAction(eventType, action);
            else
                throw new ArgumentOutOfRangeException(string.Format("{0} is not registered", deviceName));
        }

        /// <summary>
        /// Activates the named device.
        /// </summary>
        /// <param name="deviceName">Name of the device.</param>
        public void ActivateDevice(string deviceName)
        {
            GetDevice(deviceName).ActivateDevice();
        }

        /// <summary>
        /// Unactivate the named device.
        /// </summary>
        /// <param name="deviceName">Name of the device.</param>
        public void UnActivateDevice(string deviceName)
        {
            GetDevice(deviceName).DeActiveDevice();
        }

        #endregion
    }
}